﻿module Parser
(* this module represents the BJK Core language parser interface.
   It allows parsing a string or an input file. *)
open System.Collections.Generic
open System.IO
open Microsoft.FSharp.Text.Lexing
open CoreLanguageParser
open CoreLanguageLexer

(* Parses a string. Returns a Core.Cmd - the AST matching the parsed program. *)
let parseString(x : string) : Core.Cmd =
    let lexbuf = LexBuffer<_>.FromString x
    CoreLanguageLexer.varString := ""
    CoreLanguageLexer.varIndex := 0
    CoreLanguageLexer.varTable.Clear()
    let resultingAST =
        try (CoreLanguageParser.PROG CoreLanguageLexer.tokenize) lexbuf
        with e ->
            let pos = lexbuf.EndPos
            let line = pos.pos_lnum + 1
            let character = pos.pos_cnum - pos.pos_bol
            let message = e.Message
            let lastToken = new System.String(lexbuf.Lexeme)
            //let () = failwith ("Parse failed at line " + line.ToString() + ", column " + column.ToString() + "  :\nLast token: " + lastToken + "\n")
            printf "error near line %d, character %d\nlast loken: %A\n%s\n" line character lastToken (e.ToString())
            let () = failwith (sprintf "Parse failed near line %d, character %d\nlast loken: %A\n" line character lastToken)
            Core.Skip
    resultingAST

(* Parses a file. Returns Core.Cmd - the AST matching the parsed program. *)
let parseFile(filename : string) : Core.Cmd = parseString <| File.ReadAllText filename

(* a function for printing of the variable name to index mapping which was generated by the last call to 'parse' *)
let parserLastVarMapping() = !(CoreLanguageLexer.varString)
let parserLastVarToIndexMap() =
    let vt = CoreLanguageLexer.varTable
    let vt' = new Dictionary<int, string>()
    for k in CoreLanguageLexer.varTable.Keys do
        vt'.Add(vt.[k], k)
    vt'